import pygame
import easygui
import sys
import tkinter.filedialog
import json
from pygame.locals import *

pygame.init()
WIDTH = 800
HIGH = 480
UNIT = 20
W_I_D = 50
H_E_I = 30
fpsClock = pygame.time.Clock()
win = pygame.display.set_mode((WIDTH, HIGH))


class BG:
    win = None
    image = pygame.image.load('图片/borgar.png')
    map = [[' ' for i in range(12)] for j in range(12)]
    x = 0
    y = 0
    BOX = 0
    inter = -1
    history = []

    # 无输入，读取地图，存入地图函数，无输出
    def __init__(self, win):
        self.win = win

    def load(self):
        g = easygui.choicebox('请选择', choices=['0001.txt', '0002.txt', '0003.txt', '0004.txt', '0005.txt', '0006.txt',
                                                 '0007.txt', '0008.txt'])
        mep = open('关卡/' + g, 'r')
        x = 0
        y = 0
        for i in mep:
            for j in i:
                if j == '@':
                    self.x = x
                    self.y = y
                elif j == 'S':
                    self.BOX += 1
                self.map[x][y] = j
                y += 1
            x += 1
            y = 0

    # 无输入，画图，无输出
    def draw(self):
        win.fill(pygame.Color(0, 0, 0))
        for i in range(12):
            for j in range(12):
                if self.map[i][j] == '#':
                    self.win.blit(self.image, (j * UNIT, i * UNIT, UNIT, UNIT), (0, 2 * UNIT, UNIT, UNIT))
                elif self.map[i][j] == '@':
                    self.x = i
                    self.y = j
                    self.win.blit(self.image, (j * UNIT, i * UNIT, UNIT, UNIT), (UNIT, 0, UNIT, UNIT))

                elif self.map[i][j] == '|':
                    self.win.blit(self.image, (j * UNIT, i * UNIT, UNIT, UNIT), (0, UNIT, UNIT, UNIT))

                elif self.map[i][j] == 'S':
                    self.win.blit(self.image, (j * UNIT, i * UNIT, UNIT, UNIT), (2 * UNIT, 0, UNIT, UNIT))
                elif self.map[i][j] == '$':
                    self.win.blit(self.image, (j * UNIT, i * UNIT, UNIT, UNIT), (60, 0, UNIT, UNIT))
                elif self.map[i][j] == '!':
                    self.win.blit(self.image, (j * UNIT, i * UNIT, UNIT, UNIT), (20, 20, UNIT, UNIT))
                else:
                    self.win.blit(self.image, (j * UNIT, i * UNIT, UNIT, UNIT), (0, 0, UNIT, UNIT))

    # 无输入，检测按键情况，输成往上下左右
    def update(self):
        if self.BOX == 0:
            end = pygame.time.get_ticks()
            easygui.msgbox('恭喜你完成游戏，用时' + str((end - start) / 1000) + "秒", ' ')
            pygame.quit()
            sys.exit()
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
            elif event.type == KEYDOWN:
                if event.key == K_RIGHT:
                    a = [(self.x, self.y + 1), (self.x, self.y + 2)]
                    self.move(a)
                elif event.key == K_LEFT:
                    a = [(self.x, self.y - 1), (self.x, self.y - 2)]
                    self.move(a)
                elif event.key == K_UP:
                    a = [(self.x - 1, self.y), (self.x - 2, self.y)]
                    self.move(a)
                elif event.key == K_DOWN:
                    a = [(self.x + 1, self.y), (self.x + 2, self.y)]
                    self.move(a)
                elif event.key == K_F1:
                    if self.inter != 0:
                        self.inter -= 1
                        self.x = self.history[self.inter][0]
                        self.y = self.history[self.inter][1]
                        self.map[self.history[self.inter][0]][self.history[self.inter][1]] = self.history[self.inter][2]
                        self.map[self.history[self.inter][4]][self.history[self.inter][5]] = self.history[self.inter][6]
                        self.map[self.history[self.inter][8]][self.history[self.inter][9]] = self.history[self.inter][
                            10]

                elif event.key == K_n:
                    if self.inter != (len(self.history) - 1):
                        self.map[self.history[self.inter][0]][self.history[self.inter][1]] = self.history[self.inter][3]
                        self.map[self.history[self.inter][4]][self.history[self.inter][5]] = self.history[self.inter][7]
                        self.map[self.history[self.inter][8]][self.history[self.inter][9]] = self.history[self.inter][
                            11]
                        self.inter += 1
                # 如果按下s,就保存
                elif event.key == K_F2:
                    # 文件内容
                    mydict = {
                        "map": self.map, "x": self.x, "y": self.y, "history": self.history, "step": self.inter
                    }
                    filename = tkinter.filedialog.asksaveasfilename(filetypes=[("文本文件", "*.txt")])
                    # 只有返回不为空，则必然是选择了一个文件对象
                    if filename:
                        # 注意，文件名可能没有后缀，需要手动添加
                        if not filename.endswith('.txt'):
                            filename += '.txt'
                        f = open(filename, 'w')
                        json.dump(mydict, f)
                        f.close()
                # 如果用户按下l
                elif event.key == K_F3:
                    # 请用户选择一个文件
                    filename = tkinter.filedialog.askopenfilename(filetypes=[("文本文件", "*.txt")])
                    # 只有返回不为空，则必然是选择了一个文件对象
                    if filename:
                        # 开始读取文件内容
                        f = open(filename, 'r')
                        mydict = json.load(f)
                        print('成功从 ' + filename + ' 中读取字典变量：')
                        self.map = mydict['map']
                        self.x = mydict['x']
                        self.y = mydict['y']
                        self.history = mydict['history']
                        self.inter = mydict['step']
                        f.close()

    # 无输入，改变矩阵，无输出
    def move(self, a):
        # 如果右边是墙
        if self.map[a[0][0]][a[0][1]] == '#':
            return
        # 如果右边是箱子或红点箱且右右边是箱子或墙
        if ((self.map[a[0][0]][a[0][1]] == 'S' or self.map[a[0][0]][a[0][1]] == '$') and (
                (self.map[a[1][0]][a[1][1]] == '#' or self.map[a[1][0]][a[1][1]] == 'S'))):
            return
        c = self.map[self.x][self.y]
        d = self.map[a[0][0]][a[0][1]]
        e = self.map[a[1][0]][a[1][1]]
        # 如果右边是箱子或红点箱且右右边是空白
        if ((self.map[a[0][0]][a[0][1]] == 'S' or self.map[a[0][0]][a[0][1]] == '$') and self.map[a[1][0]][
            a[1][1]] == ' '):
            self.map[a[1][0]][a[1][1]] = 'S'
            # 如果右边是箱子或红点箱且右右边是红点
        elif ((self.map[a[0][0]][a[0][1]] == 'S' or self.map[a[0][0]][a[0][1]] == '$') and self.map[a[1][0]][
            a[1][1]] == '|'):
            self.map[a[1][0]][a[1][1]] = '$'
            if self.map[a[0][0]][a[0][1]] == 'S':
                self.BOX -= 1
        # 如果右边是红点或红点箱
        if self.map[a[0][0]][a[0][1]] == '|' or self.map[a[0][0]][a[0][1]] == '$':
            self.map[a[0][0]][a[0][1]] = '!'
        else:
            self.map[a[0][0]][a[0][1]] = '@'
        # 如果自己是点人
        if self.map[self.x][self.y] == '!':
            self.map[self.x][self.y] = '|'
        else:
            self.map[self.x][self.y] = ' '
        b = [self.x, self.y, c, self.map[self.x][self.y], a[0][0], a[0][1], d, self.map[a[0][0]][a[0][1]],
             a[1][0], a[1][1], e, self.map[a[1][0]][a[1][1]]]
        self.x = a[0][0]
        self.y = a[0][1]
        self.history.append(b)
        self.inter += 1


bg = BG(win)
bg.load()
start = pygame.time.get_ticks()
while True:
    # 画背景
    bg.draw()
    bg.update()
    pygame.display.update()
    fpsClock.tick(10)
